Skip to content

[DO NOT MERGE] Yanwen/dev 1.3 - #11

Open
xuyanwen2012 wants to merge 23 commits into
release/1.3from
yanwen/dev-1.3
Open

[DO NOT MERGE] Yanwen/dev 1.3#11
xuyanwen2012 wants to merge 23 commits into
release/1.3from
yanwen/dev-1.3

Conversation

@xuyanwen2012

Copy link
Copy Markdown
Collaborator

Summary

[PLEASE REMOVE] See CONTRIBUTING.md's Pull Requests for ExecuTorch PR guidelines.

[PLEASE REMOVE] If this PR closes an issue, please add a Fixes #<issue-id> line.

[PLEASE REMOVE] If this PR introduces a fix or feature that should be the upcoming release notes, please add a "Release notes: " label. For a list of available release notes labels, check out CONTRIBUTING.md's Pull Requests.

Test plan

[PLEASE REMOVE] How did you test this PR? Please write down any manual commands you used and note down tests that you have written if applicable.

xuyanwen2012 and others added 6 commits July 8, 2026 12:39
…timization

Full snapshot of the WMMA/SDPA speckit workstream's planning docs and
speckit scaffolding as of 2026-07-08, including specs 016-023 that were
still uncommitted on quant-perf-optimization. quant-perf-optimization
itself is left untouched -- this is a copy, not a move.
… to dev

Ports the M5 EVT1 WMMA coopmat path from quant-perf-optimization into
dev/executorch: linear_qw_coopmat (4w) and linear_dq8ca_qw_coopmat (8da4w)
shaders, SDPA QK^T/AV coopmat shaders, GemmCoopmat dispatch, and the
QuantizedLinear.cpp/SDPA.cpp coopmat eligibility gates. Adds
supports_int8_cooperative_matrix() (Adapter/Device) needed to gate the
8da4w int8 coopmat path.

Also fixes two storage-override bugs found while validating the port on
device (buffer-storage export was silently collapsing to texture, so
coopmat never dispatched):
- tag_memory_meta_pass.py/utils.py: force_fp16 unconditionally forced
  ANY_TEXTURE, defeating any BUFFER storage_type_override.
- vulkan_partitioner.py: ET_VK_FORCE_BUFFER env var (used by the canonical
  export_quant.sh) was never wired to storage_type_override in dev at all.

Dropped Q4gswLinear.cpp/h from the port -- confirmed dead code (its op is
unreachable from any real export path; the real 4w coopmat dispatch lives
in QuantizedLinear.cpp).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sensitive kernel picks

TextLLMRunner::warmup() built a fresh GenerationConfig without copying
num_bos/num_eos from the real call, so warmup always tokenized with
num_bos=0 regardless of what the caller passed via --num_bos. This made
warmup's prefill exactly one token shorter than the real run's, and since
warmup executes first on the same graph, whichever shader a
DynamicDispatchNode binds on that first (wrong-shape) call sticks for the
node's lifetime -- silently forcing every later dispatch, including the
correctly-shaped real run, onto that same choice.

Found while validating the M5 EVT1 WMMA coopmat port: the real 2048-token
prefill passed every coopmat eligibility check (verified via temporary
instrumentation) yet ETDump showed the tiled kernel actually executing.
Root cause was warmup's misaligned M=2047 (vs the real run's M=2048)
binding the tiled pipeline first. Passing num_bos/num_eos through fixes it
end-to-end: linear_q4gsw_coopmat now dispatches for real with --warmup=true
(the documented default), no workaround needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sweep

Adds spec-kit docs for sweeping the dq8ca/q4gsw int8 WMMA shader's
tile-shape x subgroup-grid x subgroup-size space on M5 EVT1, reusing
022's smart-autotune methodology (analytical pruning -> staged search)
re-derived for this shader's own register/shared-memory constraints.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…5 EVT1

Re-confirms dbuf2 as the fastest loop structure for 8da4w (fresh
measurement, 6/6 shapes), then sweeps its tile/subgroup geometry via
022's analytical-pruning + staged-search methodology, re-derived for
this shader's own int8-MMA constraints (542 legal candidates, not
4w's 642 -- SUBGROUP_SIZE fixed at 64, and WG_TILE_K=64 excluded once
found incompatible with this workstream's real group_size=32).

Winner: 128x32/K16/1x2/s64 (dbuf2 loop) at 1731.0 GFLOP/s, +2.55%
over the shipped 128x64/K32/2x2/s64 config -- 3-run mean, CoV<0.3%,
correctness-verified, SPIR-V-confirmed genuine int8 coopmat dispatch.
29/542 candidates (5.4%) measured on hardware, under the 30-cap budget.

Side finding: the documented Xclipse PAL subgroup=32 compiler crash
did not reproduce on the current driver -- flagged for a follow-up
feature (results/subgroup32-reverification.md), not acted on here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 63b5ce897a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +233 to +235
if (group_size % tile_k != 0) {
return false;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject partial quantization groups before coopmat

When K is tile-aligned but not an exact multiple of group_size (for example K=288, group_size=128), this gate still enables the coopmat path. Both add_linear_qw_node and add_linear_dqa_qw_node pass K / group_size as the shader trip count, so integer truncation drops the final partial quantization group and silently omits those input channels; require K % group_size == 0 here or compute a ceil trip count before selecting coopmat.

Useful? React with 👍 / 👎.

Comment on lines +334 to +335
if (p.AType == VK_COMPONENT_TYPE_SINT8_KHR) {
supports_int8_coopmat = true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require exact int8 coopmat property match

A device can enumerate VK_COMPONENT_TYPE_SINT8_KHR for AType in a cooperative-matrix property that does not match the linear_dq8ca_q4gsw_coopmat shader's required SINT8 x SINT8 -> SINT32 16x16x16 operation. Marking support from AType alone makes supports_int8_cooperative_matrix() select the int8 coopmat shader on such devices instead of falling back, which can fail pipeline creation or run an unsupported matrix shape; match the full property tuple (B/C/result types, dimensions, and scope) before setting the flag.

Useful? React with 👍 / 👎.

xuyanwen2012 and others added 17 commits July 11, 2026 11:14
SDPA coopmat (QK^T/AV) was previously opt-in via ET_VK_SDPA_COOPMAT.
Per specs/026-sdpa-8da4w-defaults-e2e, drop the opt-in env var so it's
enabled by default wherever the existing subgroup/cooperative-matrix
capability checks already gate it; ET_VK_DISABLE_COOPMAT remains the
shared kill switch with the q4gsw linear coopmat path.

Authored with Claude Code.
Redo specs/025's 8da4w tile/subgroup sweep with SUBGROUP_SIZE as a real
axis instead of fixed-at-64, per this session's re-verification finding
that the documented compiler crash is stale but the axis is shape-
dependently incorrect/slower at the shapes checked so far.
Found a real winner: t64x64k16g21s32 (SUBGROUP_SIZE=32) hits 2207.2
GFLOP/s vs specs/025's standing 1736.0 GFLOP/s winner (+27.1%), passing
correctness across all 10 representative shapes. Correctness at
subgroup=32 is sharply tile-shape-dependent -- the two shapes prior
single-shape probes (025's T014, this session's earlier sg32test check)
happened to test are exactly the two worst shapes in a 5-shape spread.
t64x64k16g21s32 wins the isolated microbenchmark (+27.1%) but measures
~7.6% SLOWER end-to-end on Llama 3.2 1B 2048-token prefill (406.8 vs
440.1 tok/s median, 3 runs each, non-overlapping). Recommendation
downgraded from productionize_candidate to keep_shipped_baseline.
Correctness/legality finding (subgroup=32 doesn't crash the compiler,
shape-dependently correct) still stands independent of this result.
Initial Tier-2 check used Llama 3.2 1B (hidden=2048/inter=8192), but
the microbenchmark that found the winning config used 8B-shaped GEMMs
(K=4096/14336) -- an apples-to-oranges comparison caught on review.
Re-ran on the shape-matched 8B model: still slower e2e, but by -2.7%
(98.01 vs 100.73 tok/s), not the flawed -7.6% from the 1B run.
Recommendation (keep_shipped_baseline) is unchanged, but now on
correct evidence.
… with microbenchmark rank

Screened+confirmed top-8 candidates by combined specs/025+specs/026
microbenchmark rank against real e2e prefill throughput (Llama 3.1 8B,
2048-token prefill, M5 EVT1). tsweep_t64x32k32g12s64 (microbenchmark
rank 4/27) wins e2e at +9.32% over shipped baseline, non-overlapping
3-run confirmation. Both prior features' microbenchmark "winners"
(025's #1 and 026's #1) underperform e2e -- 025's own top candidate is
the single worst performer of everything measured here. User Story 2
(search extension) correctly skipped since a real winner was found in
User Story 1.
…ault

Loop structure: dbuf4 -> dbuf2 (dev never received the specs/023 dbuf2
port; porting it was required to apply the tile winner faithfully,
since the winner was found and validated at dbuf2).
Tile geometry: 128x64/K32/2x2/s64 -> 64x32/K32/1x2/s64
(tsweep_t64x32k32g12s64, specs/027-e2e-tile-sweep).

Confirmed on full dev stack (SDPA coopmat default-on, Llama 3.1 8B
8da4w buffer PTE, 2048-token prefill, M5 EVT1, pinned clocks):
131.24 -> 147.65 tok/s, +12.5%, non-overlapping 3-run ranges.
This is a real, statistically confirmed end-to-end improvement, not
just isolated-kernel GFLOP/s (specs/025's/026's own microbenchmark
"winners" turned out to be e2e regressions -- specs/027 exists
precisely because of that gap). See
specs/027-e2e-tile-sweep/results/dev-branch-production-validation.md
for the full validation writeup.
…032 results

Covers 07-11 through 07-17: 8da4w-slower-than-4w investigation (024),
paused 4w e2e tile sweep pending driver reflash authorization (028),
release-1.1/1.2/1.3 4w baseline comparison (029), M41 release/1.3 baseline
(030), release/1.3 crash survey with node-threshold workaround (031), and
the SUMD driver bisect identifying 69e887275e as the dot4_i32_i8-disabling
regression commit, with M5 EVT1 ISA/SPIR-V dumps confirming the quantized
coop kernels never declare CooperativeMatrixKHR (032).

Also excludes ISA-dump binary extensions (.elf/.tgz/.spv/.disasm/.spvasm)
from the NEWLINE linter, which had no prior exposure to these file types.
…lush hypothesis refuted)

Bisect narrowed the M5 coopmat segfault to commit 805609f0da; its proposed
GL2 cache-flush mechanism was tested and refuted same-day, with the crash
further isolated to a likely UAF in ProcessBoundResourcesForCompute.
…at paths

test_llama_microbench runs the real e2e dispatch shapes of Llama 3.2 1B/3B
and 3.1 8B (2048-token prefill, single-token decode) through the runtime's
own shader selection, comparing coopmat against tiled per shape, a
forced-tiled reference on the coopmat path's own storage type to isolate
algorithm from storage effects, and the SDPA coopmat toggle at the real
attention shapes. Correctness gates run by default; --linear/--baseline/
--sdpa/--model= filter the matrix, --list enumerates it. Because dispatch
goes through the runtime pick functions, the benchmark automatically
measures whatever tile defaults the linked backend ships, and composes with
the tsweep variant env toggles where those exist.

Authored with Claude.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyWujKVd6J6TfrKCUMWNy9
…ess failures, size prefill cache to ctx3072

Fixes from an independent methodology review of the consolidated Llama
microbenchmark. The 8da4w rows previously reported op-level time (the
activation quantize_and_pack dispatch slipped past the stale
quantize_and_pack_4w4c shader filter) while being labeled as kernel time;
rows now carry both mean_us (op-level, the e2e-relevant quantity, still
feeds the geomeans) and kernel_us (linear shader only, judges the WMMA
kernel itself), with op_x/kern_x columns in the report. The correctness
gate runs one execute_test_cases() call per case and catches the
framework's validation throw, so a numeric failure is recorded and every
failing case is listed instead of the first one killing the process. SDPA
prefill's KV cache is sized 3072 to match the real ctx3072 PTEs, which
allocate the cache at max_context_length even during prefill. Also: the
report's fallback annotation now actually prints (the coopmat-filtered
lookup made it unreachable; display uses the unfiltered buffer row while
speedups/geomeans keep the filter), a DEVICE provenance line records
adapter/timestamp-period/subgroup, and the per-model geomean row aligns
under its column.

First full run on 780M (RADV): 4w coopmat 3.08x geomean, SDPA 2.84x, but
8da4w coopmat is 0.65x -- slower than tiled on this device, kern_x
confirming it is the kernel itself rather than quantize overhead.

Authored with Claude.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Brings the ET_VK_Q4GSW_COOPMAT_VARIANT / ET_VK_DQ8CA_COOPMAT_VARIANT env-var
dispatch, the two tsweep shader templates with their compiled variant lists,
and the coopmat correctness/perf bench over from yanwen/dev-igpu so the
specs/036 sweep toolkit can run on this branch on any device. Shipped
default tile geometry is deliberately left at this branch's specs/027
values -- retuned defaults remain a per-device decision made through the
sweep protocol, not part of the machinery. Authored with Claude.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyWujKVd6J6TfrKCUMWNy9
Replaces the hand-designed sweep rounds of specs/022-035 with a committed,
one-command-per-shader pipeline for retuning coopmat tile defaults on any
new GPU: device-parametrized legality model, Optuna TPE search with batched
yaml-append/rebuild, correctness gate with dispatch proof, interleaved
control runs with drift re-baselining, temperature-0 output-hash miscompute
detection, and journal-based resume. protocol.md is the operator entry
point; contracts/ documents the result schema. Validated on 780M via a
specs/035 replay (recovers the known winner) plus a live micro-sweep, and
ships the measured verdict that the microbenchmark rank is a trustworthy
prefilter on this device (Spearman 0.91 4w / 0.999 8da4w, top-5 recall 1.0)
while e2e keeps the final word. Authored with Claude.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyWujKVd6J6TfrKCUMWNy9
…ault

linear_qw_coopmat.yaml's WG_TILE_N moves 64->128 (M/K/grid/subgroup
unchanged) and kQ4gswCoopmatDims in QuantizedLinear.cpp follows, based on
specs/036-portable-device-sweep's Optuna-driven tile sweep on M51 (samsung
xclipse 970): tsweep_t128x128k16g22s32 beat the prior 128x64/2x2 tile by
+6.8%/+7.7%/+10.1% prefill tok/s on 1B/3B/8B respectively, confirmed with
no rank flip between sizes. Re-verified through the shipped (non-tsweep-env)
code path after porting: 44/44 correctness cases pass, and 3B/8B reproduce
the predicted numbers cleanly (359.6 and 168.8 tok/s, <0.4% noise).

The sweep toolkit itself only shipped host-local (validated on 780M/RADV);
running it on M51 required a new adb/ssh backend (scripts/measure_android.py)
plus a --remote hook in sweep.py, since the device is only reachable through
an ssh hop to the adb host. Included here along with the run journals,
per-token blocklist, and sweep/validation summaries specs/036's own schema
calls for committing.

Authored with Claude.
Replaces the three fused suite flags with orthogonal ingredient axes so any
combination can be selected directly: --suite=linear,sdpa,baseline,
--variant=tiled,coopmat (aliases baseline/wmma), --regime=prefill,decode,
--warmup/--runs with a --quick preset, and --output=human|machine|both
(machine adds SPEEDUP,/GEOMEAN, CSV lines to the streamed RESULT, lines;
human prints only the tables). The all-tiled baseline suite drops out
automatically when the tiled variant is deselected, and a tiled-only SDPA
prefill run now reports unexpected_coopmat if the disable toggle failed.
Defaults reproduce the previous full run (201 cases). Authored with Claude.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a STORAGE section to the report, built from the baseline suite's
forced-tiled rows -- the only place the tiled algorithm runs on buffer
storage -- so the storage-type effect can be read directly instead of
eyeballing raw rows: prefill compares the tiled shader across storages,
decode the _coop gemv shader (force-tiled does not affect the gemv pick).
Emits per-site SPEEDUP,storage and per-scheme/regime GEOMEAN,storage lines
in machine output. Measured on 780M/RADV: tiled 4w is a uniform ~1.20x
faster on buffer across all 12 prefill sites; tiled 8da4w is
storage-insensitive (geomean 1.02x). Authored with Claude.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant